package cloud.misiro.spring.cloud.examples;

import cloud.misiro.spring.cloud.discovery.MiniDiscoveryClient;
import cloud.misiro.spring.cloud.open.feign.EnableFeignClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.List;

@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Configuration
    static class RestTemplateConfiguration {
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }

    @RestController
    static class HelloController {

        @Autowired
        private MiniDiscoveryClient miniDiscoveryClient;

        @Autowired
        private LoadBalancerClient loadBalancerClient;

        @Autowired
        private RestTemplate loadBalanceRestTemplate;

        @Autowired
        private EchoService echoService;

        private final RestTemplate restTemplate = new RestTemplate();

        @GetMapping("/hello")
        public String hello() {
            List<ServiceInstance> serviceInstances = miniDiscoveryClient.getInstances("provider-application");
            if (!serviceInstances.isEmpty()) {
                ServiceInstance serviceInstance = serviceInstances.get(0);
                URI uri = serviceInstance.getUri();
                return restTemplate.postForObject(uri.toString() + "/echo", null, String.class);
            }

            throw new RuntimeException("No service instance for provider-application found");
        }

        @GetMapping("/world")
        public String world() {
            ServiceInstance serviceInstance = loadBalancerClient.choose("provider-application");
            if (serviceInstance != null) {
                URI uri = serviceInstance.getUri();
                return restTemplate.postForObject(uri.toString() + "/echo", null, String.class);
            }

            throw new RuntimeException("No service instance for provider-application found");
        }

        @GetMapping("/foo")
        public String foo() {
            return loadBalanceRestTemplate.postForObject("http://provider-application/echo", null, String.class);
        }

        @GetMapping("/bar")
        public String bar() {
            return echoService.echo();
        }
    }
}
